package com.tool.cn.util;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.databind.type.CollectionType;

/**
 * jackson工具类
 * 
 * @author wangzh
 * 2017年12月19日 上午10:23:29
 */
public final class JsonUtil {
	private static Logger log= LoggerFactory.getLogger(JsonUtil.class);

	private static ObjectMapper objectMapper = new ObjectMapper();
	
	static{
		objectMapper.setSerializationInclusion(Include.NON_NULL); 
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setFilters(new SimpleFilterProvider().setFailOnUnknownId(false));
	}
	
	/**
	 * 对象转json字符串
	 * @param value
	 * @return
	 */
	public static String toJson(Object value){
	    try {
	    	String jsonResult = objectMapper.writeValueAsString(value);
//	    	log.info("Json format: "+ jsonResult);
			return jsonResult;
		} catch (JsonProcessingException e) {
			log.error(e.toString(),e);
		}
		return null;
	}
	
	public static String toJsonInclude(Object value, String... properties){
		try {
			String jsonResult = objectMapper.writer(
			        new SimpleFilterProvider()
			        .addFilter(AnnotationUtils.getValue(AnnotationUtils.findAnnotation(value.getClass(), JsonFilter.class)).toString(), SimpleBeanPropertyFilter.filterOutAllExcept(properties)))
			        .writeValueAsString(value);
	    	log.info("Json format: "+ jsonResult);
			return jsonResult;
		} catch (JsonProcessingException e) {
			log.error(e.toString(),e);
		}
		return null;
	}
	
	public static String toJsonExclude(Object value, String... properties){
		try {
			String jsonResult = objectMapper.writer(
			        new SimpleFilterProvider()
			        .addFilter(AnnotationUtils.getValue(AnnotationUtils.findAnnotation(value.getClass(), JsonFilter.class)).toString(), SimpleBeanPropertyFilter.serializeAllExcept(properties)))
			        .writeValueAsString(value);
	    	log.info("Json format: "+ jsonResult);
			return jsonResult;
		} catch (JsonProcessingException e) {
			log.error(e.toString(),e);
		}
		return null;
	}
	
	/**
	 * json对象转list<实体类>
	 * @param json 字符串
	 * @param cls 实体类
	 * @return
	 * @throws Exception 
	 */
	public static <T> List<T> fromJsonArray(String json,Class<T> cls) throws Exception{
		 CollectionType  t  = objectMapper.getTypeFactory().constructCollectionType(List.class, cls);
	     List<T> shxtList = objectMapper.readValue(json, t);
	     return shxtList;
	}
	
	/**
	 * json字符串转对象
	 * @param json 字符串
	 * @param cls 实体类
	 * @return
	 * @throws Exception 
	 */
	public static <T> T fromJson(String json, Class<T> cls) throws Exception{  
        if(StringUtil.isEmpty(json)){  
            return null;      
        }  
        return objectMapper.readValue(json, cls);
    } 
	
	/**
	 * json对象转实体类List<Map>集合
	 * @param json
	 * @throws Exception 
	 */
	public static <T> List<T> fromJsonArray(String json) throws Exception{  
        if(StringUtil.isEmpty(json)){  
            return null;      
        }  
        return  objectMapper.readValue(json, new TypeReference<List<T>>(){}); 
    } 
	
	/**
	 * 获取json字符串中第一层对象，string格式输出
	 * @param json
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String fromatValue(String json,String key){
		Map<String, Object> tmpMap;
		String data="";
		try {
			tmpMap = objectMapper.readValue(json, Map.class);
			if(tmpMap.get(key)==null) {
				return null;
			}
			data = String.valueOf(tmpMap.get(key));
		} catch (Exception e) {
			log.error(e.toString(),e);
		}
		return data;
	}
	
	/**
	 * 动态复杂json结构处理
	 */
	public void model(){
		 try{  
		      String str = "{\"data\":{\"birth_day\":7,\"birth_month\":6},\"errcode\":0,\"msg\":\"ok\",\"ret\":0}";  
		  
		      ObjectMapper mapper = new ObjectMapper();  
		      JsonNode root = mapper.readTree(str);  
		  
		      JsonNode data = root.path("data");  
		  
		      JsonNode birth_day = data.path("birth_day");  
		      System.out.println(birth_day.asInt());  
		        
		      JsonNode birth_month = data.path("birth_month");  
		      System.out.println(birth_month.asInt());  
		  
		      JsonNode msg = root.path("msg");  
		      System.out.println(msg.textValue());  
		  }catch (IOException e){
			  log.error(e.toString(),e);
		  }  
	}
	
	/**
	 * 解析第一层list对象
	 * @param json
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String fromatListValue(String json,String key){
		Map<String, Object> tmpMap;
		String data="";
		try {
			tmpMap = objectMapper.readValue(json, Map.class);
			List<String> dataList =  (List<String>) tmpMap.get(key);
			if(!CollectionUtil.isEmptyCollection(dataList)) {
				for(String one:dataList) {
					if(!data.equals("")) {
						data+=",";
					}
					data+=one;
				}
			}else {
				return null;
			}
			
			
		} catch (Exception e) {
			log.error(e.toString(),e);
		}
		return data;
	}
	
}
